<template>
  <a-spin :spinning="confirmLoading">
    <j-form-container :disabled="formDisabled">
      <!-- 主表单区域 -->
      <a-form-model ref="form" :model="model" :rules="validatorRules" slot="detail">
        <a-row>
          <a-col :span="8">
            <a-form-model-item label="盘点单号" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="inventoryCountNo">
              <a-input v-model="model.inventoryCountNo" placeholder="保存自动生成" disabled></a-input>
            </a-form-model-item>
          </a-col>
          <!--
          <a-col :span="8">
            <a-form-model-item label="审批流程" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="approvalFlow">
              <j-dict-select-tag
                type="list"
                v-model="model.approvalFlow"
                dictCode="inventory_count_flow"
                placeholder="请选择审批流程" />
            </a-form-model-item>
          </a-col>
          -->
          <a-col :span="8">
            <a-form-model-item label="盘点仓库" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="warehouseCode">
              <j-search-select-tag
                v-model="model.warehouseCode"
                dict="wms_warehouse,warehouse_name,warehouse_code"
              />
            </a-form-model-item>
          </a-col>
          <a-col :span="8">
            <a-form-model-item label="盘点类型" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="inventoryType">
              <j-dict-select-tag type="list" v-model="model.inventoryType" dictCode="inventory_type"
                                 placeholder="请选择盘点类型" />
            </a-form-model-item>
          </a-col>
          <a-col :span="8">
            <a-form-model-item label="盘点年月" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="inventoryMonth">
              <j-date placeholder="请选择盘点年月" v-model="model.inventoryMonth"
                      style="width: 100%"
                      date-format="YYYY-MM"></j-date>
            </a-form-model-item>
          </a-col>
          <a-col :span="8">
            <a-form-model-item label="备注" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="remark">
              <a-input v-model="model.remark" rows="4" placeholder="请输入备注" />
            </a-form-model-item>
          </a-col>
        </a-row>
      </a-form-model>
    </j-form-container>
    <!-- 子表单区域 -->
    <a-tabs v-model="activeKey" @change="handleChangeTabs">
      <a-tab-pane tab="盘点明细" :key="refKeys[0]" :forceRender="true">
        <j-vxe-table
          keep-source
          :ref="refKeys[0]"
          :loading="inventoryCountItemTable.loading"
          :columns="inventoryCountItemTable.columns"
          :dataSource="inventoryCountItemTable.dataSource"
          :maxHeight="300"
          :disabled="formDisabled"
          :rowNumber="true"
          :rowSelection="false"
          :toolbar="true"
          :toolbarConfig="{
            slots: ['prefix', 'suffix'],
            btn: [] ,
          }"
          @valueChange="handleItemChange"
        >
          <template #toolbarPrefix>
            <a-upload
              v-if="!formDisabled"
              name="file"
              :showUploadList="false"
              :multiple="false"
              :headers="tokenHeader"
              :action="importExcelUrl"
              @change="handleImportExcel">
              <a-button type="primary" icon="import">导入</a-button>
            </a-upload>
          </template>
        </j-vxe-table>
      </a-tab-pane>
    </a-tabs>
  </a-spin>
</template>

<script>

import { getAction, httpAction } from '@/api/manage'
import { JVxeTableModelMixin } from '@/mixins/JVxeTableModelMixin.js'
import { JVXETypes } from '@/components/jeecg/JVxeTable'
import {
  getRefPromise,
  VALIDATE_FAILED,
  validateFormModelAndTables
} from '@/components/jeecg/JVxeTable/utils/vxeUtils.js'
import { validateDuplicateValue } from '@/utils/util'
import JFormContainer from '@/components/jeecg/JFormContainer'
import utils from '@/utils/utils'
import dayjs from 'dayjs'
import { ACCESS_TOKEN, TENANT_ID } from '@/store/mutation-types'
import Vue from 'vue'
import store from '@/store'
import { definitionStartByDataId, isFirstInitiator } from '@views/flowable/api/definition'

export default {
  name: 'InventoryCountForm',
  mixins: [JVxeTableModelMixin],
  components: {
    JFormContainer
  },
  data() {
    return {
      labelCol: {
        xs: { span: 24 },
        sm: { span: 5 }
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 16 }
      },
      model: {},
      validatorRules: {
        approvalFlow: [
          { required: true, message: '请选择审批流程!' }
        ],
        warehouseCode: [
          { required: true, message: '请选择盘点仓库!' }
        ],
        inventoryType: [
          { required: true, message: '请选择盘点类型!' }
        ],
        inventoryMonth: [
          { required: true, message: '请选择盘点年月!' }
        ]
      },
      refKeys: ['inventoryCountItem'],
      activeKey: 'inventoryCountItem',
      // 库存盘点明细表
      inventoryCountItemTable: {
        loading: false,
        dataSource: [],
        columns: [
          /*
          {
            title: '入库单号',
            key: 'entryNumber',
            width: '140px'
          },
          */
          {
            title: '物料编码',
            key: 'materialCode',
            width: '110px'
          },
          {
            title: '物料名称',
            key: 'materialName',
            minWidth: '180px'
          },
          {
            title: '规格型号',
            key: 'specificationModel',
            width: '90px'
          },
          {
            title: '单位',
            key: 'unit_dictText',
            dictCode: 'ji_unit',
            width: '50px',
            align: 'center'
          },
          {
            title: '数量',
            key: 'quantity',
            width: '70px'
          },
          {
            title: '生产日期',
            key: 'productionDate',
            width: '100px'
          },
          {
            title: '保质期（天）',
            key: 'shelfLife',
            width: '110px',
            align: 'center'
          },
          {
            title: '批次号',
            key: 'batchNumber',
            width: '100px'
          },
          {
            title: '物料批号',
            key: 'materialBatchNumber',
            width: '120px'
          },
          {
            title: '储位',
            key: 'storageLocation',
            width: '100px'
          },
          {
            title: '入库日期',
            key: 'entryDate',
            width: '100px'
          },
          {
            title: '库龄（天）',
            key: 'inventoryAge',
            width: '100px',
            align: 'center'
          },
          {
            title: '质检状态',
            key: 'qualityInspectionStatus_dictText',
            dictCode: 'zj_status',
            width: '80px',
            align: 'center'
          },
          {
            title: '实盘数量',
            key: 'actualQuantity',
            type: JVXETypes.input,
            width: '120px',
            placeholder: '请输入${title}',
            defaultValue: '',
            validateRules: [{ required: true, message: '${title}不能为空' }]
          },
          {
            title: '差异数量',
            key: 'differenceQuantity',
            width: '100px'
          }
        ]
      },
      url: {
        add: '/wms/inventory/inventory-count/add',
        edit: '/wms/inventory/inventory-count/edit',
        queryById: '/wms/inventory/inventory-count/queryById',
        inventoryCountItem: {
          list: '/wms/inventory/inventory-count/queryInventoryCountItemByMainId'
        },
        importExcelUrl: '/wms/inventory/inventory-count/importExcelList',
        inboundRecordItem: {
          list: '/wms/inbound/inbound-record/listAll'
        }
      }
    }
  },
  props: {
    //表单禁用
    disabled: {
      type: Boolean,
      default: false,
      required: false
    },
    customFormData: {
      type: Object,
      default: () => {
        return {}
      },
      required: false
    }
  },
  computed: {
    formDisabled() {
      return this.disabled
    },
    importExcelUrl: function() {
      return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`
    },
    tokenHeader() {
      let head = { 'X-Access-Token': Vue.ls.get(ACCESS_TOKEN) }
      let tenantid = Vue.ls.get(TENANT_ID)
      if (tenantid) {
        head['tenant-id'] = tenantid
      }
      return head
    }
  },
  created() {
    // 审批进来显示业务数据
    if (this.customFormData.id != null) {
      this.model = this.customFormData
      //刷新子表数据
      this.editAfter()
    }
  },
  methods: {
    addBefore() {
      this.inventoryCountItemTable.dataSource = []
    },
    getAllTable() {
      let values = ['inventoryCountItem'].map(key => getRefPromise(this, key))
      return Promise.all(values)
    },
    /** 调用完edit()方法之后会自动调用此方法 */
    editAfter() {
      this.$nextTick(() => {
      })
      // 加载子表数据
      if (this.model.id) {
        let params = { id: this.model.id }
        this.requestSubTableData(this.url.inventoryCountItem.list, params, this.inventoryCountItemTable, () => {
          if (this.inventoryCountItemTable.dataSource && this.inventoryCountItemTable.dataSource.length > 0) {
            this.inventoryCountItemTable.dataSource.forEach(item => {
              this.$set(item, 'differenceQuantity', utils.sub(item.actualQuantity, item.quantity))
            })
          }
        })
      }
    },
    //校验所有一对一子表表单
    validateSubForm(allValues) {
      return new Promise((resolve, reject) => {
        Promise.all([]).then(() => {
          resolve(allValues)
        }).catch(e => {
          if (e.error === VALIDATE_FAILED) {
            // 如果有未通过表单验证的子表，就自动跳转到它所在的tab
            this.activeKey = e.index == null ? this.activeKey : this.refKeys[e.index]
          } else {
            console.error(e)
          }
        })
      })
    },
    /** 整理成formData */
    classifyIntoFormData(allValues) {
      let main = Object.assign(this.model, allValues.formValue)
      if (main.inventoryMonth) {
        main.inventoryMonth = dayjs(main.inventoryMonth).format('YYYY-MM-DD')
      }
      return {
        ...main,
        inventoryCountItemList: allValues.tablesValue[0].tableData.map(item => {
          item.id = null
          return item
        })
      }
    },
    validateError(msg) {
      this.$message.error(msg)
    },
    /*
    warehouseCodeChange(val) {
      const params = { warehouseCode: val }
      this.requestSubTableData(this.url.inboundRecordItem.list, params, this.inventoryCountItemTable, () => {
        if (this.inventoryCountItemTable.dataSource && this.inventoryCountItemTable.dataSource.length > 0) {
          this.inventoryCountItemTable.dataSource.forEach(item => {
            this.$set(item, 'actualQuantity', 0)
            this.$set(item, 'createTime', null)
            this.$set(item, 'updateTime', null)
            this.$set(item, 'createBy', null)
            this.$set(item, 'updateBy', null)
          })
        }
      })
    },
     */
    handleItemChange({ value, col, rowIndex }) {
      if (col.field === 'actualQuantity' && value) {
        const item = this.inventoryCountItemTable.dataSource[rowIndex]
        item.differenceQuantity = utils.sub(value, item.quantity)
      }
    },
    handleImportExcel(info) {
      this.loading = true
      if (info.file.status !== 'uploading') {
        console.log(info.file, info.fileList)
      }
      if (info.file.status === 'done') {
        this.loading = false
        if (!info.file.response.success) {
          this.$message.error(`${info.file.name} ${info.file.response.message}.`)
          return
        }
        if (info.file.response.code === 201) {
          let { message, result: { msg, fileUrl, fileName } } = info.file.response
          let href = window._CONFIG['domianURL'] + fileUrl
          this.$warning({
            title: message,
            content: (<div>
                <span>{msg}</span><br />
                <span>具体详情请 <a href={href} target="_blank" download={fileName}>点击下载</a> </span>
              </div>
            )
          })
        } else {
          this.inventoryCountItemTable.dataSource = info.file.response.result.map((item) => {
            item.actualQuantity = 0
            return item
          })
          this.$message.success(info.file.response.message || `${info.file.name} 文件导入成功`)
        }
      } else if (info.file.status === 'error') {
        this.loading = false
        if (info.file.response.status === 500) {
          let data = info.file.response
          const token = Vue.ls.get(ACCESS_TOKEN)
          if (token && data.message.includes('Token失效')) {
            this.$error({
              title: '登录已过期',
              content: '很抱歉，登录已过期，请重新登录',
              okText: '重新登录',
              mask: false,
              onOk: () => {
                store.dispatch('Logout').then(() => {
                  Vue.ls.remove(ACCESS_TOKEN)
                  window.location.reload()
                })
              }
            })
          }
        } else {
          this.$message.error(`文件上传失败: ${info.file.msg} `)
        }
      }
    },
    saveDraft() {
      this.validate(this.request)
    },
    handleSubmit() {
      this.validate(this.request, false)
    },
    validate(request, isDraft = true) {
      this.getAllTable().then(tables => {
        return validateFormModelAndTables(this.$refs.form, this.model, tables)
      }).then(allValues => {
        return this.validateSubForm(allValues)
      }).then(allValues => {
        if (typeof this.classifyIntoFormData !== 'function') {
          throw this.throwNotFunction('classifyIntoFormData')
        }
        let formData = this.classifyIntoFormData(allValues)
        // 发起请求
        return request(formData, isDraft)
      })
    },
    request(formData, isDraft = true) {
      let url = this.url.add, method = 'post'
      if (this.model.id) {
        url = this.url.edit
        method = 'put'
      }
      this.confirmLoading = true
      httpAction(url, formData, method).then((res) => {
        if (res.success) {
          if (!isDraft) {
            this.model.dataId = this.model.id || res.message
            this.applySubmit(this.model)
          }
          this.$message.success(res.message)
          this.$emit('ok')
          this.close()
        } else {
          this.$message.warning(res.message)
        }
      }).finally(() => {
        this.confirmLoading = false
      })
    },
    applySubmit(record) {
      if (record.dataId && record.dataId.length < 1) {
        this.$message.error('审批时必须传入参数dataId')
        return
      }
      //对于自定义业务，判断是否是驳回或退回的第一个发起人节点
      isFirstInitiator(record.dataId, record).then((res) => {
        if (res.success && res.result) {
          // 只有第一次能自动申请
        } else {
          const params = Object.assign({ dataId: record.dataId }, record)
          definitionStartByDataId(record.dataId, 'inventoryCountService', params)
            .then((res) => {
              if (res.success) {
                this.$message.success(res.message)
              } else {
                this.$message.error(res.message)
              }
              this.$emit('ok')
            })
        }
      })
    }
  }
}
</script>

<style scoped>
</style>